package com.bestcem.xm.member.grpc.service;

import com.bestcem.bp.grpc.v1.base.BaseTime;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.grpc.service.param.PageParam;
import com.bestcem.xm.member.grpc.service.param.SortParam;
import com.bestcem.xm.member.grpc.service.param.export.*;
import com.bestcem.xm.member.grpc.v1.common.BatchDeleteResponse;
import com.bestcem.xm.member.grpc.v1.common.Sort;
import com.bestcem.xm.member.grpc.v1.services.*;
import com.bestcem.xm.member.service.ExportService;
import com.bestcem.xm.member.service.dto.ExportRecordDTO;
import com.bestcem.xm.member.service.dto.PageDTO;
import com.google.protobuf.Timestamp;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.validation.ConstraintViolation;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 导出服务
 * @date 2021-07-24
 */
@GrpcService
public class ExportGrpcService extends ExportServiceGrpc.ExportServiceImplBase {
    /**
     * 导出服务
     */
    @Autowired
    private ExportService exportService;

    /**
     * <pre>
     * 导出记录列表查询
     * </pre>
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void listExportRecords(ListExportRecordsRequest request, StreamObserver<ListExportRecordsResponse> responseObserver) {
        ListExportRecordsResponse.Builder builder = ListExportRecordsResponse.newBuilder();

        Page page = request.getPage();
        List<Sort> sorts = request.getSortByList();
        List<SortParam> sortParams = sorts.stream().map(s -> new SortParam(s.getProperty(), s.getDirection().getNumber())).collect(Collectors.toList());

        ListExportRecordsParam param = new ListExportRecordsParam();
        param.setOrgId(request.getOrgId());
        param.setOpUserId(request.getOpUserId());
        param.setMemberTypeEnum(EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberTypeValue()));
        param.setSortParams(sortParams);
        param.setPageParam(new PageParam(page.getPage(), page.getSize()));

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询
        ServiceResult<PageDTO<ExportRecordDTO>> result = exportService.listExportRecords(param);
        if(result.isSuccess()){
            PageDTO<ExportRecordDTO> pageDTO = result.getData();
            List<ExportRecord> exportRecords = pageDTO.getRows().stream().map(this::convertFrom).collect(Collectors.toList());
            builder.setStatus(RpcStatusResult.success());
            builder.addAllRecords(exportRecords);
            builder.setTotal(pageDTO.getTotal().intValue());
        }else{
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * <pre>
     * 单个导出记录
     * </pre>
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void getExportRecord(GetExportRecordRequest request, StreamObserver<GetExportRecordResponse> responseObserver) {
        GetExportRecordResponse.Builder builder = GetExportRecordResponse.newBuilder();

        GetExportRecordParam param = new GetExportRecordParam();
        param.setOrgId(request.getOrgId());
        param.setId(request.getId());

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询
        ServiceResult<ExportRecordDTO> result = exportService.getExportRecord(param);
        if(result.isSuccess()){
            ExportRecord exportRecord = this.convertFrom(result.getData());
            builder.setStatus(RpcStatusResult.success());
            builder.setRecord(exportRecord);
        }else{
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * <pre>
     * 删除导出记录
     * </pre>
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void batchDeleteExportRecords(BatchDeleteExportRecordsRequest request, StreamObserver<BatchDeleteResponse> responseObserver) {
        BatchDeleteResponse.Builder builder = BatchDeleteResponse.newBuilder();

        // 参数校验
        BatchDeleteExportRecordsParam param = new BatchDeleteExportRecordsParam(request.getOrgId(), request.getIdsList());
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询
        ServiceResult<Integer> result = exportService.batchDeleteExportRecords(param);
        if(result.isSuccess()){
            builder.setStatus(RpcStatusResult.success());
            builder.setDeleteCount(result.getData());
        }else{
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * <pre>
     * 导出进度查询
     * </pre>
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void getExportProgress(GetExportProgressRequest request, StreamObserver<GetExportProgressResponse> responseObserver) {
        GetExportProgressResponse.Builder builder = GetExportProgressResponse.newBuilder();

        // 暂时未加入orgId
        GetExportProgressParam param = new GetExportProgressParam("", request.getId());

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询
        ServiceResult<Float> result = exportService.getExportProgress(param);
        if(result.isSuccess()){
            builder.setStatus(RpcStatusResult.success());
            builder.setProgress(result.getData());
        }else{
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 导出联系人
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void exportMember(ExportMemberRequest request, StreamObserver<ExportMemberResponse> responseObserver) {
        ExportMemberResponse.Builder builder = ExportMemberResponse.newBuilder();

        ExportMemberParam param = new ExportMemberParam();
        param.setOrgId(request.getOrgId());
        param.setMemberType(request.getMemberTypeValue());
        param.setIds(request.getIdsList());
        param.setPattern(request.getPattern());
        param.setCondition(request.getCondition());
        // 联系人导出
        ServiceResult<String> result = exportService.exportMember(param);
        if(result.isSuccess()){
            builder.setStatus(RpcStatusResult.success());
            builder.setId(result.getData());
        }else{
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    // 将ExportRecordDTO转化为ExportRecord
    private ExportRecord convertFrom(ExportRecordDTO exportRecordDTO){
        BaseTime.Builder baseBuilder = BaseTime.newBuilder();
        if(exportRecordDTO.getCreateTime() != null){
            baseBuilder.setCreateTime(Timestamp.newBuilder().setSeconds(exportRecordDTO.getCreateTime().getTime()));
        }
        ExportRecord.Builder builder = ExportRecord.newBuilder();
        builder.setFileName(exportRecordDTO.getFileName());
        builder.setFileType(exportRecordDTO.getFileType());
        builder.setFileSize(exportRecordDTO.getFileSize());
        builder.setFileUrl(exportRecordDTO.getFileUrl());
        builder.setBase(baseBuilder.build());
        return builder.build();
    }
}
